/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = rtcp_header.c                                      */
/*  NOTE      =                                                    */
/*  DATE      = 2015/07/20 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <frct_comm.h>
#include <ctype.h>

#include "rtcp_comm.h"
#include "rtcp_core.h"

/*******************************************************************************
*  FUNC     :  分析RTCP头
*           :  *p_payload                           (数据内容)
*           :  ui_payload_len                       (数据长度)
*  RTN      :  APM_L7_IS_YES                        (是Oracle协议)
*              APM_L7_IS_UNKNOWN                    (不能判断该协议)
*  NOTE     :
*******************************************************************************/
int rtcp_header_detect(char *p_payload
                    , unsigned int ui_payload_len)
{
    unsigned char uc_tmp;
    int i_version;
    int i_padding;
    unsigned char uc_pt;
    unsigned short *p_us_pkt_len;
    unsigned int ui_pkt_len;
    int i_first_pkt = FR_NO;
    unsigned int ui_pkt_offset = 0;

    while (ui_pkt_offset < ui_payload_len)
    {
        if (ui_payload_len - ui_pkt_offset < 4)
            goto unknown;

        uc_tmp = (unsigned char) *(p_payload + ui_pkt_offset);
        i_version = APM_RTCP_VERSION(uc_tmp);
        if (i_version != 2)
            goto unknown;

        i_padding = APM_RTCP_PADDING(uc_tmp);

        uc_pt = (unsigned char) *(p_payload + ui_pkt_offset + APM_RTCP_PKT_PT_OFFSET);
        if (uc_pt < APM_RTCP_PT_MIN || uc_pt > APM_RTCP_PT_MAX)
            goto unknown;

        if (i_first_pkt == FR_NO)
        {
            if (uc_pt != RTCP_PT_SR && uc_pt != RTCP_PT_RR)
                goto unknown;
            i_first_pkt = FR_YES;
        }

        p_us_pkt_len = (unsigned short *) (p_payload + ui_pkt_offset + APM_RTCP_PKT_LEN_OFFSET);
        ui_pkt_len = (ntohs(*p_us_pkt_len) + 1) * 4;
        if (ui_pkt_len < 4)
            goto unknown;

        ui_pkt_offset += ui_pkt_len;

        // 除了最后一个包，前面的包的padding值只可能是0
        if (ui_pkt_offset < ui_payload_len && i_padding != 0)
            goto unknown;

        RTCP_PRINT_ALERT("uc_tmp:[%d]\n", uc_tmp);
        RTCP_PRINT_ALERT("i_version:[%d]\n", i_version);
        RTCP_PRINT_ALERT("i_padding:[%d]\n", i_padding);
        RTCP_PRINT_ALERT("uc_pt:[%d]\n", uc_pt);
        RTCP_PRINT_ALERT("ui_pkt_len:[%d]\n", ui_pkt_len);
        RTCP_PRINT_ALERT("ui_pkt_offset:[%d]\n", ui_pkt_offset);
        RTCP_PRINT_ALERT("ui_payload_len:[%d]\n\n", ui_payload_len);
    }
    if (ui_pkt_offset != ui_payload_len)
        goto unknown;

    return APM_L7_IS_YES;
unknown:
    return APM_L7_IS_UNKNOWN;
}
